using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using System.ComponentModel.DataAnnotations;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 部门管理控制器
    /// 提供部门的增删改查、层级管理、权限配置等功能的 RESTful API
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    [Authorize]
    public class DepartmentsController : ControllerBase
    {
        private readonly IDepartmentAppService _departmentService;
        private readonly ILogger<DepartmentsController> _logger;

        public DepartmentsController(
            IDepartmentAppService departmentService,
            ILogger<DepartmentsController> logger)
        {
            _departmentService = departmentService;
            _logger = logger;
        }

        // 分页查询
        [HttpGet]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<PagedResultDto<DepartmentDto>>> GetPaged(
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 20,
            [FromQuery] string? keyword = null,
            [FromQuery] long? parentId = null,
            [FromQuery] byte? status = null)
        {
            try
            {
                var (items, total) = await _departmentService.GetPagedAsync(pageIndex, pageSize, keyword, parentId, status);
                return Ok(new PagedResultDto<DepartmentDto>(items, total, pageIndex, pageSize));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting paged departments");
                return BadRequest(new { message = ex.Message });
            }
        }

        // 全量
        [HttpGet("all")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<DepartmentDto>>> GetAll()
        {
            try
            {
                var result = await _departmentService.GetAllAsync();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting all departments");
                return BadRequest(new { message = ex.Message });
            }
        }

        // 按ID
        [HttpGet("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<DepartmentDto>> GetById(long id)
        {
            try
            {
                var result = await _departmentService.GetByIdAsync(id);
                if (result == null) return NotFound();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting department {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 按编码
        [HttpGet("code/{code}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(404)]
        [AllowAnonymous]
        public async Task<ActionResult<DepartmentDto>> GetByCode(string code)
        {
            try
            {
                var result = await _departmentService.GetByCodeAsync(code);
                if (result == null) return NotFound();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting department by code {Code}", code);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 子部门
        [HttpGet("{parentId:long}/children")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<DepartmentDto>>> GetChildren(long parentId)
        {
            try
            {
                var result = await _departmentService.GetChildrenAsync(parentId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting children for department {ParentId}", parentId);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 树形
        [HttpGet("hierarchy")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<IEnumerable<DepartmentDto>>> GetHierarchy()
        {
            try
            {
                var result = await _departmentService.GetHierarchyAsync();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting department hierarchy");
                return BadRequest(new { message = ex.Message });
            }
        }

        // 用户部门路径
        [HttpGet("user/{userId:long}/path")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<IEnumerable<DepartmentDto>>> GetUserDepartmentPath(long userId)
        {
            try
            {
                var result = await _departmentService.GetUserDepartmentPathAsync(userId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting department path for user {UserId}", userId);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 搜索
        [HttpGet("search")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<PagedResultDto<DepartmentDto>>> Search(
            [FromQuery][Required] string keyword,
            [FromQuery] int pageIndex = 1,
            [FromQuery] int pageSize = 20)
        {
            try
            {
                var (items, total) = await _departmentService.SearchAsync(keyword, pageIndex, pageSize);
                return Ok(new PagedResultDto<DepartmentDto>(items, total, pageIndex, pageSize));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error searching departments with keyword {Keyword}", keyword);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 创建
        [HttpPost]
        [ProducesResponseType(201)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<DepartmentDto>> Create([FromBody] DepartmentDto dto)
        {
            try
            {
                var created = await _departmentService.CreateAsync(dto);
                return CreatedAtAction(nameof(GetById), new { id = created.Id }, created);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating department");
                return BadRequest(new { message = ex.Message });
            }
        }

        // 更新
        [HttpPut("{id:long}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(400)]
        public async Task<ActionResult<DepartmentDto>> Update(long id, [FromBody] DepartmentDto dto)
        {
            try
            {
                dto.Id = id;
                var updated = await _departmentService.UpdateAsync(dto);
                return Ok(updated);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating department {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 删除
        [HttpDelete("{id:long}")]
        [ProducesResponseType(200)]
        public async Task<ActionResult> Delete(long id)
        {
            try
            {
                var ok = await _departmentService.DeleteAsync(id);
                return ok ? Ok(new { success = true }) : BadRequest(new { success = false });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting department {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 批量删除
        [HttpPost("batch-delete")]
        [ProducesResponseType(200)]
        public async Task<ActionResult> BatchDelete([FromBody] BatchDeleteRequest request)
        {
            try
            {
                var deleted = await _departmentService.BatchDeleteAsync(request.Ids);
                return Ok(new { success = true, count = deleted });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error batch deleting departments");
                return BadRequest(new { message = ex.Message });
            }
        }

        // 更新状态
        [HttpPut("{id:long}/status")]
        [ProducesResponseType(200)]
        public async Task<ActionResult> UpdateStatus(long id, [FromQuery][Required] byte status)
        {
            try
            {
                var ok = await _departmentService.UpdateStatusAsync(id, status);
                return ok ? Ok(new { success = true }) : BadRequest(new { success = false });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating department status {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 移动部门
        [HttpPut("{id:long}/move")]
        [ProducesResponseType(200)]
        public async Task<ActionResult> Move(long id, [FromQuery] long? newParentId)
        {
            try
            {
                var ok = await _departmentService.MoveDepartmentAsync(id, newParentId);
                return ok ? Ok(new { success = true }) : BadRequest(new { success = false });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error moving department {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 设置负责人
        [HttpPut("{id:long}/manager")]
        [ProducesResponseType(200)]
        public async Task<ActionResult> SetManager(long id, [FromQuery] long? managerId)
        {
            try
            {
                var ok = await _departmentService.SetManagerAsync(id, managerId);
                return ok ? Ok(new { success = true }) : BadRequest(new { success = false });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error setting department manager {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 编码是否存在
        [HttpGet("code-exists")]
        [ProducesResponseType(200)]
        [AllowAnonymous]
        public async Task<ActionResult<object>> CodeExists([FromQuery][Required] string code, [FromQuery] long? excludeId = null)
        {
            try
            {
                var exists = await _departmentService.CodeExistsAsync(code, excludeId);
                return Ok(new { exists });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error checking code exists {Code}", code);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 是否可删除
        [HttpGet("{id:long}/can-delete")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<object>> CanDelete(long id)
        {
            try
            {
                var can = await _departmentService.CanDeleteAsync(id);
                return Ok(new { canDelete = can });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error checking can delete department {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 部门用户
        [HttpGet("{id:long}/users")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<IEnumerable<UserDto>>> GetUsers(long id, [FromQuery] bool includeChildren = false)
        {
            try
            {
                var users = await _departmentService.GetDepartmentUsersAsync(id, includeChildren);
                return Ok(users);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting department users {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 统计
        [HttpGet("{id:long}/stats")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<object>> GetStatistics(long id)
        {
            try
            {
                var stats = await _departmentService.GetDepartmentStatisticsAsync(id);
                return Ok(stats);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting department statistics {Id}", id);
                return BadRequest(new { message = ex.Message });
            }
        }

        // 同步层级
        [HttpPost("sync-hierarchy")]
        [ProducesResponseType(200)]
        public async Task<ActionResult<object>> SyncHierarchy()
        {
            try
            {
                var ok = await _departmentService.SyncHierarchyAsync();
                return Ok(new { success = ok });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error syncing department hierarchy");
                return BadRequest(new { message = ex.Message });
            }
        }
    }
}
